{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "provenance": [],
      "machine_shape": "hm",
      "authorship_tag": "ABX9TyNkb2fmxCFnR5Ap6QVqy0CP",
      "include_colab_link": true
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    },
    "language_info": {
      "name": "python"
    }
  },
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "view-in-github",
        "colab_type": "text"
      },
      "source": [
        "<a href=\"https://colab.research.google.com/github/tomasonjo/blogs/blob/master/llm/neo4j_genai.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "u_ZmmAKpM74W",
        "outputId": "315b6054-77d5-4ec4-fb22-73d104b7bb65"
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Requirement already satisfied: neo4j-graphrag in /usr/local/lib/python3.10/dist-packages (0.6.3)\n",
            "Collecting neo4j-genai\n",
            "  Downloading neo4j_genai-0.6.0-py3-none-any.whl.metadata (9.6 kB)\n",
            "Requirement already satisfied: eval-type-backport<0.3.0,>=0.2.0 in /usr/local/lib/python3.10/dist-packages (from neo4j-graphrag) (0.2.0)\n",
            "Requirement already satisfied: neo4j<6.0.0,>=5.17.0 in /usr/local/lib/python3.10/dist-packages (from neo4j-graphrag) (5.24.0)\n",
            "Requirement already satisfied: pydantic<3.0.0,>=2.6.3 in /usr/local/lib/python3.10/dist-packages (from neo4j-graphrag) (2.9.1)\n",
            "Requirement already satisfied: pypdf<5.0.0,>=4.3.1 in /usr/local/lib/python3.10/dist-packages (from neo4j-graphrag) (4.3.1)\n",
            "Requirement already satisfied: types-mock<6.0.0.0,>=5.1.0.20240425 in /usr/local/lib/python3.10/dist-packages (from neo4j-graphrag) (5.1.0.20240425)\n",
            "Requirement already satisfied: types-requests<3.0.0.0,>=2.31.0.20240218 in /usr/local/lib/python3.10/dist-packages (from neo4j-graphrag) (2.32.0.20240914)\n",
            "Requirement already satisfied: pytz in /usr/local/lib/python3.10/dist-packages (from neo4j<6.0.0,>=5.17.0->neo4j-graphrag) (2024.2)\n",
            "Requirement already satisfied: annotated-types>=0.6.0 in /usr/local/lib/python3.10/dist-packages (from pydantic<3.0.0,>=2.6.3->neo4j-graphrag) (0.7.0)\n",
            "Requirement already satisfied: pydantic-core==2.23.3 in /usr/local/lib/python3.10/dist-packages (from pydantic<3.0.0,>=2.6.3->neo4j-graphrag) (2.23.3)\n",
            "Requirement already satisfied: typing-extensions>=4.6.1 in /usr/local/lib/python3.10/dist-packages (from pydantic<3.0.0,>=2.6.3->neo4j-graphrag) (4.12.2)\n",
            "Requirement already satisfied: urllib3>=2 in /usr/local/lib/python3.10/dist-packages (from types-requests<3.0.0.0,>=2.31.0.20240218->neo4j-graphrag) (2.0.7)\n",
            "Downloading neo4j_genai-0.6.0-py3-none-any.whl (92 kB)\n",
            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m92.3/92.3 kB\u001b[0m \u001b[31m4.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[?25hInstalling collected packages: neo4j-genai\n",
            "Successfully installed neo4j-genai-0.6.0\n"
          ]
        }
      ],
      "source": [
        "!pip install neo4j-graphrag neo4j-genai openai langchain_text_splitters"
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "# https://stackoverflow.com/questions/58535604/installing-pygrahviz-in-google-colab\n",
        "!apt install libgraphviz-dev\n",
        "!pip install pygraphviz"
      ],
      "metadata": {
        "id": "Zbg4rT14SLik"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "from neo4j_graphrag.experimental.components.schema import (\n",
        "    SchemaBuilder,\n",
        "    SchemaEntity,\n",
        "    SchemaProperty,\n",
        "    SchemaRelation,\n",
        ")\n",
        "\n",
        "schema_builder = SchemaBuilder()\n",
        "\n",
        "schema = await schema_builder.run(\n",
        "    entities=[\n",
        "        SchemaEntity(\n",
        "            label=\"Gene\",\n",
        "            properties=[\n",
        "                SchemaProperty(name=\"gene_id\", type=\"STRING\"),\n",
        "                SchemaProperty(name=\"symbol\", type=\"STRING\"),\n",
        "                SchemaProperty(name=\"full_name\", type=\"STRING\"),\n",
        "                SchemaProperty(name=\"chromosome\", type=\"STRING\"),\n",
        "                SchemaProperty(name=\"location\", type=\"STRING\"),\n",
        "            ],\n",
        "        ),\n",
        "        SchemaEntity(\n",
        "            label=\"Disease\",\n",
        "            properties=[\n",
        "                SchemaProperty(name=\"disease_id\", type=\"STRING\"),\n",
        "                SchemaProperty(name=\"name\", type=\"STRING\"),\n",
        "                SchemaProperty(name=\"category\", type=\"STRING\"),\n",
        "                SchemaProperty(name=\"description\", type=\"STRING\"),\n",
        "            ],\n",
        "        ),\n",
        "        SchemaEntity(\n",
        "            label=\"Drug\",\n",
        "            properties=[\n",
        "                SchemaProperty(name=\"drug_id\", type=\"STRING\"),\n",
        "                SchemaProperty(name=\"name\", type=\"STRING\"),\n",
        "                SchemaProperty(name=\"type\", type=\"STRING\"),\n",
        "                SchemaProperty(name=\"mechanism_of_action\", type=\"STRING\"),\n",
        "            ],\n",
        "        ),\n",
        "        SchemaEntity(\n",
        "            label=\"Protein\",\n",
        "            properties=[\n",
        "                SchemaProperty(name=\"protein_id\", type=\"STRING\"),\n",
        "                SchemaProperty(name=\"name\", type=\"STRING\"),\n",
        "                SchemaProperty(name=\"sequence\", type=\"STRING\"),\n",
        "                SchemaProperty(name=\"function\", type=\"STRING\"),\n",
        "            ],\n",
        "        ),\n",
        "        SchemaEntity(\n",
        "            label=\"Pathway\",\n",
        "            properties=[\n",
        "                SchemaProperty(name=\"pathway_id\", type=\"STRING\"),\n",
        "                SchemaProperty(name=\"name\", type=\"STRING\"),\n",
        "                SchemaProperty(name=\"description\", type=\"STRING\"),\n",
        "            ],\n",
        "        ),\n",
        "    ],\n",
        "    relations=[\n",
        "        SchemaRelation(\n",
        "            label=\"ASSOCIATED_WITH\",\n",
        "        ),\n",
        "        SchemaRelation(\n",
        "            label=\"TARGETS\",\n",
        "        ),\n",
        "        SchemaRelation(\n",
        "            label=\"INTERACTS_WITH\",\n",
        "        ),\n",
        "        SchemaRelation(\n",
        "            label=\"PART_OF\",\n",
        "        ),\n",
        "        SchemaRelation(\n",
        "            label=\"INVOLVED_IN\",\n",
        "        ),\n",
        "    ],\n",
        "    potential_schema=[\n",
        "        (\"Gene\", \"ASSOCIATED_WITH\", \"Disease\"),\n",
        "        (\"Gene\", \"TARGETS\", \"Drug\"),\n",
        "        (\"Protein\", \"INTERACTS_WITH\", \"Protein\"),\n",
        "        (\"Drug\", \"TARGETS\", \"Protein\"),\n",
        "        (\"Pathway\", \"PART_OF\", \"Gene\"),\n",
        "        (\"Gene\", \"INVOLVED_IN\", \"Pathway\"),\n",
        "        (\"Disease\", \"INVOLVED_IN\", \"Pathway\"),\n",
        "    ],\n",
        ")"
      ],
      "metadata": {
        "id": "7vvHWrhuM_o0"
      },
      "execution_count": 6,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "schema"
      ],
      "metadata": {
        "id": "GaLlYcdaQ1eI",
        "outputId": "20a5c81b-d35b-4d99-e51a-b4d343995739",
        "colab": {
          "base_uri": "https://localhost:8080/"
        }
      },
      "execution_count": 7,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "SchemaConfig(entities={'Gene': {'label': 'Gene', 'description': '', 'properties': [{'name': 'gene_id', 'type': 'STRING', 'description': ''}, {'name': 'symbol', 'type': 'STRING', 'description': ''}, {'name': 'full_name', 'type': 'STRING', 'description': ''}, {'name': 'chromosome', 'type': 'STRING', 'description': ''}, {'name': 'location', 'type': 'STRING', 'description': ''}]}, 'Disease': {'label': 'Disease', 'description': '', 'properties': [{'name': 'disease_id', 'type': 'STRING', 'description': ''}, {'name': 'name', 'type': 'STRING', 'description': ''}, {'name': 'category', 'type': 'STRING', 'description': ''}, {'name': 'description', 'type': 'STRING', 'description': ''}]}, 'Drug': {'label': 'Drug', 'description': '', 'properties': [{'name': 'drug_id', 'type': 'STRING', 'description': ''}, {'name': 'name', 'type': 'STRING', 'description': ''}, {'name': 'type', 'type': 'STRING', 'description': ''}, {'name': 'mechanism_of_action', 'type': 'STRING', 'description': ''}]}, 'Protein': {'label': 'Protein', 'description': '', 'properties': [{'name': 'protein_id', 'type': 'STRING', 'description': ''}, {'name': 'name', 'type': 'STRING', 'description': ''}, {'name': 'sequence', 'type': 'STRING', 'description': ''}, {'name': 'function', 'type': 'STRING', 'description': ''}]}, 'Pathway': {'label': 'Pathway', 'description': '', 'properties': [{'name': 'pathway_id', 'type': 'STRING', 'description': ''}, {'name': 'name', 'type': 'STRING', 'description': ''}, {'name': 'description', 'type': 'STRING', 'description': ''}]}}, relations={'ASSOCIATED_WITH': {'label': 'ASSOCIATED_WITH', 'description': '', 'properties': []}, 'TARGETS': {'label': 'TARGETS', 'description': '', 'properties': []}, 'INTERACTS_WITH': {'label': 'INTERACTS_WITH', 'description': '', 'properties': []}, 'PART_OF': {'label': 'PART_OF', 'description': '', 'properties': []}, 'INVOLVED_IN': {'label': 'INVOLVED_IN', 'description': '', 'properties': []}}, potential_schema=[('Gene', 'ASSOCIATED_WITH', 'Disease'), ('Gene', 'TARGETS', 'Drug'), ('Protein', 'INTERACTS_WITH', 'Protein'), ('Drug', 'TARGETS', 'Protein'), ('Pathway', 'PART_OF', 'Gene'), ('Gene', 'INVOLVED_IN', 'Pathway'), ('Disease', 'INVOLVED_IN', 'Pathway')])"
            ]
          },
          "metadata": {},
          "execution_count": 7
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "import os\n",
        "\n",
        "os.environ[\"OPENAI_API_KEY\"] = \"sk-\""
      ],
      "metadata": {
        "id": "8FnrIU2WQj0N"
      },
      "execution_count": 3,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "from langchain_text_splitters import CharacterTextSplitter\n",
        "from neo4j_graphrag.experimental.components.text_splitters.langchain import LangChainTextSplitterAdapter\n",
        "splitter = LangChainTextSplitterAdapter(\n",
        "    CharacterTextSplitter(chunk_size=500, chunk_overlap=100, separator=\".\")\n",
        ")\n",
        "docs = await splitter.run(text=\"\"\"\n",
        "Joan of Arc (French: Jeanne d'Arc [ʒan daʁk]; Middle French: Jehanne Darc [ʒəˈãnə ˈdark]; c. 1412 – 30 May 1431) is a patron saint of France, honored as a defender of the French nation for her role in the siege of Orléans and her insistence on the coronation of Charles VII of France during the Hundred Years' War. Claiming to be acting under divine guidance, she became a military leader who transcended gender roles and gained recognition as a savior of France.\n",
        "\n",
        "Joan was born to a propertied peasant family at Domrémy in northeast France. In 1428, she requested to be taken to Charles VII, later testifying that she was guided by visions from the archangel Michael, Saint Margaret, and Saint Catherine to help him save France from English domination. Convinced of her devotion and purity, Charles sent Joan, who was about seventeen years old, to the siege of Orléans as part of a relief army. She arrived at the city in April 1429, wielding her banner and bringing hope to the demoralized French army. Nine days after her arrival, the English abandoned the siege. Joan encouraged the French to aggressively pursue the English during the Loire Campaign, which culminated in another decisive victory at Patay, opening the way for the French army to advance on Reims unopposed, where Charles was crowned as the King of France with Joan at his side. These victories boosted French morale, paving the way for their final triumph in the Hundred Years' War several decades later.\n",
        "\n",
        "After Charles's coronation, Joan participated in the unsuccessful siege of Paris in September 1429 and the failed siege of La Charité in November. Her role in these defeats reduced the court's faith in her. In early 1430, Joan organized a company of volunteers to relieve Compiègne, which had been besieged by the Burgundians—French allies of the English. She was captured by Burgundian troops on 23 May. After trying unsuccessfully to escape, she was handed to the English in November. She was put on trial by Bishop Pierre Cauchon on accusations of heresy, which included blaspheming by wearing men's clothes, acting upon visions that were demonic, and refusing to submit her words and deeds to the judgment of the church. She was declared guilty and burned at the stake on 30 May 1431, aged about nineteen.\n",
        "\n",
        "In 1456, an inquisitorial court reinvestigated Joan's trial and overturned the verdict, declaring that it was tainted by deceit and procedural errors. Joan has been revered as a martyr, and viewed as an obedient daughter of the Roman Catholic Church, an early feminist, and a symbol of freedom and independence. After the French Revolution, she became a national symbol of France. In 1920, Joan of Arc was canonized by Pope Benedict XV and, two years later, was declared one of the patron saints of France. She is portrayed in numerous cultural works, including literature, music, paintings, sculptures, and theater.\n",
        "\n",
        "Name\n",
        "Joan of Arc's name was written in a variety of ways. There is no standard spelling of her name before the sixteenth century; her last name was usually written as \"Darc\" without an apostrophe, but there are variants such as \"Tarc\", \"Dart\" or \"Day\". Her father's name was written as \"Tart\" at her trial.[3] She was called \"Jeanne d'Ay de Domrémy\" in Charles VII's 1429 letter granting her a coat of arms.[4] Joan may never have heard herself called \"Jeanne d'Arc\". The first written record of her being called by this name is in 1455, 24 years after her death.[3]\n",
        "\n",
        "She was not taught to read and write in her childhood,[5] and so dictated her letters.[6] She may later have learned to sign her name, as some of her letters are signed, and she may even have learned to read.[7] Joan referred to herself in the letters as Jeanne la Pucelle (\"Joan the Maiden\") or as la Pucelle (\"the Maiden\"), emphasizing her virginity, and she signed \"Jehanne\". In the sixteenth century, she became known as the \"Maid of Orleans\".[6]\n",
        "\n",
        "Birth and historical background\n",
        "A map of France, divided into various sections\n",
        "France, 1429[8]\n",
        "  Controlled by Henry VI of England\n",
        "  Controlled by Philip III of Burgundy\n",
        "  Controlled by Charles VII of France\n",
        "Joan of Arc was born c. 1412[9] in Domrémy, a small village in the Meuse valley now in the Vosges department in the north-east of France.[10] Her date of birth is unknown and her statements about her age were vague.[11][b] Her parents were Jacques d'Arc and Isabelle Romée. Joan had three brothers and a sister.[15] Her father was a peasant farmer[16] with about 50 acres (20 ha) of land,[17] and he supplemented the family income as a village official, collecting taxes and heading the local watch.[18]\n",
        "\n",
        "She was born during the Hundred Years' War between England and France, which had begun in 1337[19] over the status of English territories in France and English claims to the French throne.[20] Nearly all the fighting had taken place in France, devastating its economy.[21] At the time of Joan's birth, France was divided politically. The French king Charles VI had recurring bouts of mental illness and was often unable to rule;[22] his brother Louis, Duke of Orléans, and his cousin John the Fearless, Duke of Burgundy, quarreled over the regency of France. In 1407, the Duke of Burgundy ordered the assassination of the Duke of Orléans,[23] precipitating a civil war.[24] Charles of Orléans succeeded his father as duke at the age of thirteen and was placed in the custody of Bernard, Count of Armagnac; his supporters became known as \"Armagnacs\", while supporters of the Duke of Burgundy became known as \"Burgundians\".[23] The future French king Charles VII had assumed the title of Dauphin (heir to the throne) after the deaths of his four older brothers[25] and was associated with the Armagnacs.[26]\n",
        "\n",
        "Henry V of England exploited France's internal divisions when he invaded in 1415.[27] The Burgundians took Paris in 1418.[28] In 1419, the Dauphin offered a truce to negotiate peace with the Duke of Burgundy, but the duke was assassinated by Charles's Armagnac partisans during the negotiations. The new duke of Burgundy, Philip the Good, allied with the English.[29] Charles VI accused the Dauphin of murdering the Duke of Burgundy and declared him unfit to inherit the French throne.[30] During a period of illness, Charles's wife Isabeau of Bavaria stood in for him and signed the Treaty of Troyes,[31] which gave their daughter Catherine of Valois in marriage to Henry V, granted the succession of the French throne to their heirs, and effectively disinherited the Dauphin.[32] This caused rumors that the Dauphin was not King Charles VI's son, but the offspring of an adulterous affair between Isabeau and the murdered duke of Orléans.[33] In 1422, Henry V and Charles VI died within two months of each other; the 9-month-old Henry VI of England was the nominal heir of the Anglo-French dual monarchy as agreed in the treaty, but the Dauphin also claimed the French throne.[34]\n",
        "\n",
        "Early life\n",
        "Joan in dress facing left in profile, holding banner in her right hand and sheathed sword in her left.\n",
        "Earliest extant representation of Joan of Arc;[35] drawing by Clément de Fauquembergue (May 1429, French National Archives)[c]\n",
        "In her youth, Joan did household chores, spun wool, helped her father in the fields and looked after their animals. Her mother provided Joan's religious education.[37] Much of Domrémy lay in the Duchy of Bar,[38] whose precise feudal status was unclear;[39] though surrounded by pro-Burgundian lands, its people were loyal to the Armagnac cause.[40] By 1419, the war had affected the area,[41] and in 1425, Domrémy was attacked and cattle were stolen.[42] This led to a sentiment among villagers that the English must be expelled from France to achieve peace. Joan had her first vision after this raid.[43]\n",
        "\n",
        "Joan later testified that when she was thirteen, c. 1425, a figure she identified as Saint Michael surrounded by angels appeared to her in the garden.[44] After this vision, she said she wept because she wanted them to take her with them.[45] Throughout her life, she had visions of St. Michael,[46] a patron saint of the Domrémy area who was seen as a defender of France.[47] She stated that she had these visions frequently and that she often had them when the church bells were rung.[48] Her visions also included St. Margaret and St. Catherine; although Joan never specified, they were probably Margaret of Antioch and Catherine of Alexandria—those most known in the area.[49] Both were known as virgin saints who strove against powerful enemies, were tortured and martyred for their beliefs, and preserved their virtue to the death.[50] Joan testified that she swore a vow of virginity to these voices.[51] When a young man from her village alleged that she had broken a promise of marriage, Joan stated that she had made him no promises,[52] and his case was dismissed by an ecclesiastical court.[53]\n",
        "\n",
        "During Joan's youth, a prophecy circulating in the French countryside, based on the visions of Marie Robine of Avignon [fr], promised an armed virgin would come forth to save France.[54] Another prophecy, attributed to Merlin, stated that a virgin carrying a banner would put an end to France's suffering.[55] Joan implied she was this promised maiden, reminding the people around her that there was a saying that France would be destroyed by a woman but would be restored by a virgin.[56][d] In May 1428,[59] she asked her uncle to take her to the nearby town of Vaucouleurs, where she petitioned the garrison commander, Robert de Baudricourt, for an armed escort to the Armagnac court at Chinon. Baudricourt harshly refused and sent her home.[60] In July, Domrémy was raided by Burgundian forces[61] which set fire to the town, destroyed the crops, and forced Joan, her family and the other townspeople to flee.[62] She returned to Vaucouleurs in January 1429. Her petition was refused again,[63] but by this time she had gained the support of two of Baudricourt's soldiers, Jean de Metz and Bertrand de Poulengy.[64] Meanwhile, she was summoned to Nancy under safe conduct by Charles II, Duke of Lorraine, who had heard about Joan during her stay at Vaucouleurs. The duke was ill and thought she might have supernatural powers that could cure him. She offered no cures, but reprimanded him for living with his mistress.[65]\n",
        "\n",
        "Henry V's brothers, John of Lancaster, 1st Duke of Bedford, and Humphrey, Duke of Gloucester, had continued the English conquest of France.[66] Most of northern France, Paris, and parts of southwestern France were under Anglo-Burgundian control. The Burgundians controlled Reims, the traditional site for the coronation of French kings; Charles had not yet been crowned, and doing so at Reims would help legitimize his claim to the throne.[67] In July 1428, the English had started to surround Orléans and had nearly isolated it from the rest of Charles's territory by capturing many of the smaller bridge towns on the Loire River.[68] Orléans was strategically important as the last obstacle to an assault on the remainder of Charles's territory.[69] According to Joan's later testimony, it was around this period that her visions told her to leave Domrémy to help the Dauphin Charles.[70] Baudricourt agreed to a third meeting with Joan in February 1429, around the time the English captured an Armagnac relief convoy at the Battle of the Herrings during the Siege of Orléans. Their conversations,[71] along with Metz and Poulengy's support,[72] convinced Baudricourt to allow her to go to Chinon for an audience with the Dauphin. Joan traveled with an escort of six soldiers.[73] Before leaving, Joan put on men's clothes,[74] which were provided by her escorts and the people of Vaucouleurs.[75] She continued to wear men's clothes for the remainder of her life.[76]\n",
        "\n",
        "Chinon\n",
        "Miniature of Charles the seventh of France.\n",
        "Charles VII of France by Jean Fouquet (c. 1444, Louvre, Paris)\n",
        "Charles VII met Joan for the first time at the Royal Court in Chinon in late February or early March 1429,[77] when she was seventeen[78] and he was twenty-six.[79] She told him that she had come to raise the siege of Orléans and to lead him to Reims for his coronation.[80] They had a private exchange that made a strong impression on Charles; Jean Pasquerel, Joan's confessor, later testified that Joan told him she had reassured the Dauphin that he was Charles VI's son and the legitimate king.[81]\n",
        "\n",
        "Charles and his council needed more assurance,[82] sending Joan to Poitiers to be examined by a council of theologians, who declared that she was a good person and a good Catholic.[83] They did not render a decision on the source of Joan's inspiration, but agreed that sending her to Orléans could be useful to the king[84] and would test whether her inspiration was of divine origin.[85] Joan was then sent to Tours to be physically examined by women directed by Charles's mother-in-law Yolande of Aragon, who verified her virginity.[86] This was to establish if she could indeed be the prophesied virgin savior of France,[87] to show the purity of her devotion,[88] and to ensure she had not consorted with the Devil.[89]\n",
        "\n",
        "The Dauphin, reassured by the results of these tests, commissioned plate armor for her. She designed her own banner and had a sword brought to her from under the altar in the church at Sainte-Catherine-de-Fierbois.[90] Around this time she began calling herself \"Joan the Maiden\", emphasizing her virginity as a sign of her mission.[6]\n",
        "\n",
        "Before Joan's arrival at Chinon, the Armagnac strategic situation was bad but not hopeless.[91] The Armagnac forces were prepared to endure a prolonged siege at Orléans,[92] the Burgundians had recently withdrawn from the siege due to disagreements about territory,[93] and the English were debating whether to continue.[94] Nonetheless, after almost a century of war, the Armagnacs were demoralized.[95] Once Joan joined the Dauphin's cause, her personality began to raise their spirits,[96] inspiring devotion and the hope of divine assistance.[97] Her belief in the divine origin of her mission turned the longstanding Anglo-French conflict over inheritance into a religious war.[94] Before beginning the journey to Orléans, Joan dictated a letter to the Duke of Bedford warning him that she was sent by God to drive him out of France.[98]\n",
        "\n",
        "Military campaigns\n",
        "Orléans\n",
        "Joan of Arc on horseback with armor and holding banner being greeted by the people of Orléans.\n",
        "Joan of Arc enters Orléans by Jean-Jacques Scherrer (1887, Musée des Beaux-Arts d'Orléans)\n",
        "In the last week of April 1429, Joan set out from Blois as part of an army carrying supplies for the relief of Orléans.[99] She arrived there on 29 April[100] and met the commander Jean de Dunois, the Bastard of Orléans.[101] Orléans was not completely cut off, and Dunois got her into the city, where she was greeted enthusiastically.[102] Joan was initially treated as a figurehead to raise morale,[103] flying her banner on the battlefield.[104] She was not given any formal command[105] or included in military councils[106] but quickly gained the support of the Armagnac troops. She always seemed to be present where the fighting was most intense, she frequently stayed with the front ranks, and she gave them a sense she was fighting for their salvation.[107] Armagnac commanders would sometimes accept the advice she gave them, such as deciding what position to attack, when to continue an assault, and how to place artillery.[108]\n",
        "\n",
        "On 4 May, the Armagnacs went on the offensive, attacking the outlying bastille de Saint-Loup (fortress of Saint Loup). Once Joan learned of the attack, she rode out with her banner to the site of the battle, a mile east of Orléans. She arrived as the Armagnac soldiers were retreating after a failed assault. Her appearance rallied the soldiers, who attacked again and took the fortress.[109] On 5 May, no combat occurred since it was Ascension Thursday, a feast day. She dictated another letter to the English warning them to leave France and had it tied to a bolt, which was fired by a crossbowman.[110]\n",
        "\n",
        "The Armagnacs resumed their offensive on 6 May, capturing Saint-Jean-le-Blanc, which the English had deserted.[111] The Armagnac commanders wanted to stop, but Joan encouraged them to launch an assault on les Augustins, an English fortress built around a monastery.[112] After its capture,[113] the Armagnac commanders wanted to consolidate their gains, but Joan again argued for continuing the offensive.[114] On the morning of 7 May, the Armagnacs attacked the main English stronghold, les Tourelles. Joan was wounded by an arrow between the neck and shoulder while holding her banner in the trench on the south bank of the river but later returned to encourage the final assault that took the fortress.[115] The English retreated from Orléans on 8 May, ending the siege.[116]\n",
        "\n",
        "At Chinon, Joan had declared that she was sent by God.[117] At Poitiers, when she was asked to show a sign demonstrating this claim, she replied that it would be given if she were brought to Orléans. The lifting of the siege was interpreted by many people to be that sign.[118] Prominent clergy such as Jacques Gélu [fr], Archbishop of Embrun,[119] and the theologian Jean Gerson[120] wrote treatises in support of Joan after this victory.[121] In contrast, the English saw the ability of this peasant girl to defeat their armies as proof she was possessed by the devil.[122]\n",
        "\n",
        "Loire Campaign\n",
        " Joan of Arc\n",
        "Allegiance\tKingdom of France\n",
        "Conflict\tHundred Years' War\n",
        "Important locations\n",
        "MapWikimedia | © OpenStreetMapAbout OpenStreetMapsMaps: terms of usenoneRouenRouen- Joan's final prison, place of trail and execution: 25 December 1430–30 May 1431.Arras- Joan imprisoned here after her second escape attempt: November–December 1430Beaurevoir- Joan imprisoned here after her first escape attempt; Jumps from tower in another escape attempt: June–November 1430.Beaulieu-les-Fontaines- Joan is imprisoned in the castle keep and attempts to escape: May–June 1430.Margny- Site of Joan's capture by Burgundians: 23 May 1430.CompiègneSiege of Compiègne: 14–23 May 1493Lagny- Site of battle against Franquet D'Arras: April 1430.Melun- Liberated by Joan's forces: April 1430.La CharitéSiege of La Charité: 24 November–25 December 1429Siege of Saint-Pierre-le-Moûtier: October–November 1429ParisSiege of Paris: 3–8 September 1429ReimsJoan and Charles arrive at Reims: 16 July 1429Battle of Patay: 18 June 1429Battle of Beaugency: on 16 June 1429Battle of Meung-sur-Loire: on 15–16 June 1429Battle of Jargeau: on 11 June 1429OrléansSiege of Orléans: 29 April 1429- 8 May 1429Blois- Joan joins the army to relieve the siege of Orléans: 24 April 1429.Tours- Joan's virginity attested; Joan receives her armor, banner and sword: early April 1429.Poitiers- Joan examined by theologians of Charles VII's court during March–April 1429ChinonChinon- Joan meets Charles VII at his court: March 1429Nancy, France- Joan meets Charles II, Duke of Lorraine: early winter 1429VaucouleursVaucouleurs- Site of Joan's three meetings with Robert de Baudricourt to request being sent to Charles VII's Court: May and January 1428, February 1429.DomrémyDomrémy- Joan's birthplace and childhood home\n",
        "  Joan's journey to Chinon\n",
        "  Orléans and Loire Campaign\n",
        "  March to Reims\n",
        "  Reims and the Siege of Paris\n",
        "  Campaign against Perrinet Gressard\n",
        "  Compiègne\n",
        "  Other locations\n",
        "After the success at Orléans, Joan insisted that the Armagnac forces should advance promptly toward Reims to crown the Dauphin.[123] Charles allowed her to accompany the army under the command of John II, Duke of Alençon,[124] who collaboratively worked with Joan and regularly heeded her advice.[125] Before advancing toward Reims, the Armagnacs needed to recapture the bridge towns along the Loire: Jargeau, Meung-sur-Loire, and Beaugency. This would clear the way for Charles and his entourage, who would have to cross the Loire near Orléans to get from Chinon to Reims.[126]\n",
        "\n",
        "The campaign to clear the Loire towns began on 11 June when the Armagnac forces led by Alençon and Joan arrived at Jargeau[127] and forced the English to withdraw inside the town's walls. Joan sent a message to the English to surrender; they refused[128] and she advocated for a direct assault on the walls the next day.[129] By the end of the day, the town was taken. The Armagnac took few prisoners and many of the English who surrendered were killed.[130] During this campaign, Joan continued to serve in the thick of battle. She began scaling a siege ladder with her banner in hand but before she could climb the wall, she was struck by a stone which split her helmet.[131]\n",
        "\n",
        "Alençon and Joan's army advanced on Meung-sur-Loire. On 15 June, they took control of the town's bridge, and the English garrison withdrew to a castle on the Loire's north bank.[132] Most of the army continued on the south bank of the Loire to besiege the castle at Beaugency.[133]\n",
        "\n",
        "Meanwhile, the English army from Paris under the command of Sir John Fastolf had linked up with the garrison in Meung and traveled along the north bank of the Loire to relieve Beaugency.[134] Unaware of this, the English garrison at Beaugency surrendered on 18 June.[135] The main English army retreated toward Paris; Joan urged the Armagnacs to pursue them, and the two armies clashed at the Battle of Patay later that day. The English had prepared their forces to ambush an Armagnac attack with hidden archers,[136] but the Armagnac vanguard detected and scattered them. A rout ensued that decimated the English army. Fastolf escaped with a small band of soldiers, but many of the English leaders were captured.[137] Joan arrived at the battlefield too late to participate in the decisive action,[138] but her encouragement to pursue the English had made the victory possible.[139]\n",
        "\n",
        "Coronation and siege of Paris\n",
        "Miniature of coronation of King Charles the seventh of France\n",
        "Coronation of Charles VII in Guillaume de Nangis' Chronicon abbreviatum regum Francorum; Joan of Arc stands holding a banner of France to his left. Unknown author (15th century).\n",
        "After the destruction of the English army at Patay, some Armagnac leaders argued for an invasion of English-held Normandy, but Joan remained insistent that Charles must be crowned.[140] The Dauphin agreed, and the army left Gien on 29 June to march on Reims.[141] The advance was nearly unopposed.[142] The Burgundian-held town of Auxerre surrendered on 3 July after three days of negotiations,[143] and other towns in the army's path returned to Armagnac allegiance without resistance.[144] Troyes, which had a small garrison of English and Burgundian troops,[145] was the only one to resist. After four days of negotiation, Joan ordered the soldiers to fill the city's moat with wood and directed the placement of artillery. Fearing an assault, Troyes negotiated a surrender.[146]\n",
        "\n",
        "Reims opened its gates on 16 July 1429. Charles, Joan, and the army entered in the evening, and Charles's consecration took place the following morning.[147] Joan was given a place of honor at the ceremony,[148] and announced that God's will had been fulfilled.[149]\n",
        "\n",
        "After the consecration, the royal court negotiated a truce of fifteen days with the Duke of Burgundy,[150] who promised he would try to arrange the transfer of Paris to the Armagnacs while continuing negotiations for a definitive peace. At the end of the truce, Burgundy reneged on his promise.[151] Joan and the Duke of Alençon favored a quick march on Paris,[152] but divisions in Charles's court and continued peace negotiations with Burgundy led to a slow advance.[153]\n",
        "\n",
        "As the Armagnac army approached Paris, many of the towns along the way surrendered without a fight.[154] On 15 August, the English forces under the Duke of Bedford confronted the Armagnacs near Montépilloy in a fortified position that the Armagnac commanders thought was too strong to assault. Joan rode out in front of the English positions to try to provoke them to attack. They refused, resulting in a standoff.[155] The English retreated the following day.[156] The Armagnacs continued their advance and launched an assault on Paris on 8 September.[157] During the fighting, Joan was wounded in the leg by a crossbow bolt. She remained in a trench beneath the city walls until she was rescued after nightfall.[158] The Armagnacs had suffered 1,500 casualties.[159] The following morning, Charles ordered an end to the assault. Joan was displeased[160] and argued that the attack should be continued. She and Alençon had made fresh plans to attack Paris, but Charles dismantled a bridge approaching Paris that was necessary for the attack and the Armagnac army had to retreat.[161]\n",
        "\n",
        "After the defeat at Paris, Joan's role in the French court diminished. Her aggressive independence did not agree with the court's emphasis on finding a diplomatic solution with Burgundy, and her role in the defeat at Paris reduced the court's faith in her.[162] Scholars at the University of Paris argued that she failed to take Paris because her inspiration was not divine.[163] In September, Charles disbanded the army, and Joan was not allowed to work with the Duke of Alençon again.[164]\n",
        "\n",
        "Campaign against Perrinet Gressart\n",
        "A human figure on horseback, with the horse pointing left. The figure is wearing armor and carrying an orange banner. The horse is white and has red accessories.\n",
        "Miniature depicting Jeanne d'Arc from The Lives of Famous Women, by Jean Pichore [fr] (1506, Musée Dobrée, Nantes, France)\n",
        "In October, Joan was sent as part of a force to attack the territory of Perrinet Gressart [fr], a mercenary who had served the Burgundians and English.[165] The army besieged Saint-Pierre-le-Moûtier, which fell after Joan encouraged a direct assault on 4 November. The army then tried unsuccessfully to take La-Charité-sur-Loire in November and December and had to abandon their artillery during the retreat.[166] This defeat further diminished Joan's reputation.[167]\n",
        "\n",
        "Joan returned to court at the end of December,[168] where she learned that she and her family had been ennobled by Charles as a reward for her services to him and the kingdom.[169] Before the September attack on Paris, Charles had negotiated a four-month truce with the Burgundians,[170] which was extended until Easter 1430.[171] During this truce, the French court had no need for Joan.[172]\n",
        "\n",
        "Siege of Compiègne and capture\n",
        "Main article: Siege of Compiègne\n",
        "The Duke of Burgundy began to reclaim towns which had been ceded to him by treaty but had not submitted.[173] Compiègne was one such town[174] of many in areas which the Armagnacs had recaptured over the previous few months.[175] Joan set out with a company of volunteers at the end of March 1430 to relieve the town, which was under siege.[176] This expedition did not have the explicit permission of Charles, who was still observing the truce.[177] Some writers suggest that Joan's expedition to Compiègne without documented permission from the court was a desperate and treasonable action,[178] but others have argued that she could not have launched the expedition without the financial support of the court.[179]\n",
        "\n",
        "In April, Joan arrived at Melun, which had expelled its Burgundian garrison.[180] As Joan advanced, her force grew as other commanders joined her.[181] Joan's troops advanced to Lagny-sur-Marne and defeated an Anglo-Burgundian force commanded by the mercenary Franquet d'Arras who was captured. Typically, he would have been ransomed or exchanged by the capturing force, but Joan allowed the townspeople to execute him after a trial.[182]\n",
        "\n",
        "Joan in armor and surcoat being pulled off her horse by soldiers.\n",
        "Mural Joan captured by the Burgundians at Compiègne by Jules-Eugène Lenepveu (c. 1886–1890, Panthéon, Paris)\n",
        "Joan reached Compiègne on 14 May.[183] After defensive forays against the Burgundian besiegers,[184] she was forced to disband the majority of the army because it had become too difficult for the surrounding countryside to support.[185] Joan and about 400 of her remaining soldiers entered the town.[186]\n",
        "\n",
        "On 23 May 1430, Joan accompanied an Armagnac force which sortied from Compiègne to attack the Burgundian camp at Margny, northeast of the town. The attack failed, and Joan was captured;[187] she agreed to surrender to a pro-Burgundian nobleman named Lyonnel de Wandomme, a member of Jean de Luxembourg's contingent.[188] who quickly moved her to his castle at Beaulieu-les-Fontaines near Noyes.[189] After her first attempt to escape, she was transferred to Beaurevoir Castle. She made another escape attempt while there, jumping from a window of a tower and landing in a dry moat; she was injured but survived.[190] In November, she was moved to the Burgundian town of Arras.[191]\n",
        "\n",
        "The English and Burgundians rejoiced that Joan had been removed as a military threat.[192] The English negotiated with their Burgundian allies to pay Joan's ransom and transfer her to their custody. Bishop Pierre Cauchon of Beauvais, a partisan supporter of the Duke of Burgundy and the English crown,[193] played a prominent part in these negotiations,[194] which were completed in November.[195] The final agreement called for the English to pay 10,000 livres tournois to obtain her from Luxembourg.[196] After the English paid the ransom, they moved Joan to Rouen, their main headquarters in France.[197] There is no evidence that Charles tried to save Joan once she was transferred to the English.[198]\n",
        "\n",
        "Trials and execution\n",
        "Trial\n",
        "Main article: Trial of Joan of Arc\n",
        "Joan of Arc facing left addressing assessors, scribes. She has soldiers behind her\n",
        "The Trial of Joan of Arc, by Louis Maurice Boutet de Monvel (1909–1910, National Gallery of Art, Washington, D.C.)\n",
        "Joan was put on trial for heresy[199] in Rouen on 9 January 1431.[200] She was accused of having blasphemed by wearing men's clothes, of acting upon visions that were demonic, and of refusing to submit her words and deeds to the church because she claimed she would be judged by God alone.[201] Joan's captors downplayed the secular aspects of her trial by submitting her judgment to an ecclesiastical court, but the trial was politically motivated.[202] Joan testified that her visions had instructed her to defeat the English and crown Charles, and her success was argued to be evidence she was acting on behalf of God.[203] If unchallenged, her testimony would invalidate the English claim to the rule of France[204] and undermine the University of Paris,[205] which supported the dual monarchy ruled by an English king.[206]\n",
        "\n",
        "The verdict was a foregone conclusion.[207] Joan's guilt could be used to compromise Charles's claims to legitimacy by showing that he had been consecrated by the act of a heretic.[208] Cauchon served as the ordinary judge of the trial.[209] The English subsidized the trial,[210] including payments to Cauchon[211] and Jean Le Maître,[212] who represented the Inquisitor of France.[213] All but 8 of the 131 clergy who participated in the trial were French[214] and two thirds were associated with the University of Paris,[215] but most were pro-Burgundian and pro-English.[216]\n",
        "\n",
        "miniature of Pierre Couchon\n",
        "Miniature of Pierre Cauchon presiding at Joan of Arc's trial, unknown author (15th century, Bibliothèque nationale de France)\n",
        "Cauchon attempted to follow correct inquisitorial procedure,[217] but the trial had many irregularities.[218] Joan should have been in the hands of the church during the trial and guarded by women,[219] but instead was imprisoned by the English and guarded by male soldiers under the command of the Duke of Bedford.[220] Contrary to canon law, Cauchon had not established Joan's infamy before proceeding with the trial.[221] Joan was not read the charges against her until well after her interrogations began.[222] The procedures were below inquisitorial standards,[223] subjecting Joan to lengthy interrogations[224] without legal counsel.[225] One of the trial clerics stepped down because he felt the testimony was coerced and its intention was to entrap Joan;[226] another challenged Cauchon's right to judge the trial and was jailed.[227] There is evidence that the trial records were falsified.[228]\n",
        "\n",
        "During the trial, Joan showed great control.[229] She induced her interrogators to ask questions sequentially rather than simultaneously, refer back to their records when appropriate, and end the sessions when she requested.[230] Witnesses at the trial were impressed by her prudence when answering questions.[231] For example, in one exchange she was asked if she knew she was in God's grace. The question was meant as a scholarly trap, as church doctrine held that nobody could be certain of being in God's grace. If she answered positively, she would have been charged with heresy; if negatively, she would have confessed her own guilt. Joan avoided the trap by stating that if she was not in God's grace, she hoped God would put her there, and if she was in God's grace then she hoped she would remain so.[232] One of the court notaries at her trial later testified that the interrogators were stunned by her answer.[233] To convince her to submit, Joan was shown the instruments of torture. When she refused to be intimidated, Cauchon met with about a dozen assessors (clerical jurors) to vote on whether she should be tortured. The majority decided against it.[234]\n",
        "\n",
        "In early May, Cauchon asked the University of Paris to deliberate on twelve articles summarizing the accusation of heresy. The university approved the charges.[235] On 23 May, Joan was formally admonished by the court.[236] The next day, she was taken out to the churchyard of the abbey of Saint-Ouen for public condemnation. As Cauchon began to read Joan's sentence, she agreed to submit. She was presented with an abjuration document, which included an agreement that she would not bear arms or wear men's clothing.[237] It was read aloud to her,[238] and she signed it.[239][e]\n",
        "\n",
        "Execution\n",
        "Public heresy was a capital crime,[242] in which an unrepentant or relapsed heretic could be given over to the judgment of the secular courts and punished by death.[243] Having signed the abjuration, Joan was no longer an unrepentant heretic but could be executed if convicted of relapsing into heresy.[244]\n",
        "\n",
        "As part of her abjuration, Joan was required to renounce wearing men's clothes.[245] She exchanged her clothes for a woman's dress and allowed her head to be shaved.[246] She was returned to her cell and kept in chains[247] instead of being transferred to an ecclesiastical prison.[248] Witnesses at the rehabilitation trial stated that Joan was subjected to mistreatment and rape attempts, including one by an English noble,[249] and that guards placed men's clothes in her cell, forcing her to wear them.[250] Cauchon was notified that Joan had resumed wearing male clothing. He sent clerics to admonish her to remain in submission, but the English prevented them from visiting her.[251]\n",
        "\n",
        "Joan in red dress being bound to a stake as a group of men look on\n",
        "Miniature of Joan's Execution from The Vigils of King Charles VII, anonymous (c. 1484, Bibliothèque nationale de France)\n",
        "On 28 May, Cauchon went to Joan's cell, along with several other clerics. According to the trial record, Joan said that she had gone back to wearing men's clothes because it was more fitting that she dress like a man while being held with male guards, and that the judges had broken their promise to let her go to mass and to release her from her chains. She stated that if they fulfilled their promises and placed her in a decent prison, she would be obedient.[252] When Cauchon asked about her visions, Joan stated that the voices had blamed her for abjuring out of fear, and that she would not deny them again. As Joan's abjuration had required her to deny her visions, this was sufficient to convict her of relapsing into heresy and to condemn her to death.[253] The next day, forty-two assessors were summoned to decide Joan's fate. Two recommended that she be abandoned to the secular courts immediately; the rest recommended that the abjuration be read to her again and explained.[254] In the end, they voted unanimously that Joan was a relapsed heretic and should be abandoned to the secular power, the English, for punishment.[255]\n",
        "\n",
        "At about the age of nineteen, Joan was executed on 30 May 1431. In the morning, she was allowed to receive the sacraments despite the court process requiring they be denied to heretics.[256] She was then taken to Rouen's Vieux-Marché (Old Marketplace), where she was publicly read her sentence of condemnation.[257] At this point, she should have been turned over to the appropriate authority, the bailiff of Rouen, for secular sentencing, but instead was delivered directly to the English[258] and tied to a tall plastered pillar for execution by burning.[259] She asked to view a cross as she died, and was given one by an English soldier made from a stick, which she kissed and placed next to her chest.[260] A processional crucifix was fetched from the church of Saint-Saveur. She embraced it before her hands were bound, and it was held before her eyes during her execution.[261] After her death, her remains were thrown into the Seine River.[262]\n",
        "\n",
        "Aftermath and rehabilitation trial\n",
        "Main article: Rehabilitation trial of Joan of Arc\n",
        "A group of highly detailed and realistic painted plaster statues depicting four men wearing various ecclesiastical garments. They are arranged in a complex composition around a representation of Joan of Arc on a set of stairs.\n",
        "Monument Commemorating the Rehabilitation of Joan of Arc, a plaster work by Émile Pinchon [fr]; Joan stands in the foreground, facing figures from her rehabilitation trial (1909, Cathédrale Notre-Dame de Noyon).[f]\n",
        "The military situation was not changed by Joan's execution. Her triumphs had raised Armagnac morale, and the English were not able to regain momentum.[264] Charles remained king of France,[265] despite a rival coronation held for the ten-year-old Henry VI of England at Notre-Dame cathedral in Paris in 1431.[266] In 1435, the Burgundians signed the Treaty of Arras, abandoning their alliance with England.[267] Twenty-two years after Joan's death, the war ended with a French victory at the Battle of Castillon in 1453,[268] and the English were expelled from all of France except Calais.[269]\n",
        "\n",
        "Joan's execution created a political liability for Charles, implying that his consecration as the king of France had been achieved through the actions of a heretic.[270] On 15 February 1450, a few months after he regained Rouen, Charles ordered Guillaume Bouillé, a theologian and former rector of the University of Paris, to open an inquest.[271] In a brief investigation, Bouillé interviewed seven witnesses of Joan's trial and concluded that the judgment of Joan as a heretic was arbitrary. She had been a prisoner of war treated as a political prisoner, and was put to death without basis.[272] Bouillé's report could not overturn the verdict but it opened the way for the later retrial.[273]\n",
        "\n",
        "In 1452, a second inquest into Joan's trial was opened by Cardinal Guillaume d'Estouteville, papal legate and relative of Charles, and Jean Bréhal, the recently appointed Inquisitor of France,[274] who interviewed about 20 witnesses.[275] The inquest was guided by 27 articles describing how Joan's trial had been biased.[276] Immediately after the inquest, d'Estouteville went to Orléans on 9 June and granted an indulgence to those who participated in the ceremonies in Joan's honor on 8 May commemorating the lifting of the siege.[277]\n",
        "\n",
        "For the next two years d'Estouteville and Bréhal worked on the case.[278] Bréhal forwarded a petition from Joan's mother, Isabelle, and Joan's two brothers Jean and Pierre, to Pope Nicholas V in 1454.[279] Bréhal submitted a summary of his findings to theologians and lawyers in France and Italy,[280] as well as a professor at the University of Vienna,[281] most of whom gave opinions favorable to Joan.[282] After Nicholas V died in early 1455, the new pope Callixtus III gave permission for a rehabilitation trial, and appointed three commissioners to oversee the process: Jean Juvénal des Ursins, archbishop of Reims; Guillaume Chartier, bishop of Paris; and Richard Olivier de Longueil, bishop of Coutances. They chose Bréhal as Inquisitor.[283]\n",
        "\n",
        "The rehabilitation trial began on 7 November 1455 at Notre Dame Cathedral when Joan's mother publicly delivered a formal request for her daughter's rehabilitation,[284] and ended on 7 July 1456 at Rouen Cathedral, having heard from about 115 witnesses.[285] The court found that the original trial was unjust and deceitful; Joan's abjuration, execution and their consequences were nullified.[286] In his summary of the trial, Bréhal suggested that Cauchon and the assessors who supported him might be guilty of malice and heresy.[287] To emphasize the court's decision, a copy of the Articles of Accusation was formally torn up. The court ordered that a cross should be erected on the site of Joan's execution.[288]\n",
        "\n",
        "Visions\n",
        "Joan seated and looking forward with her furled banner while an angel whispers in her ear. An armored figure with fleur-de-lys banner is blowing a horn in the background.\n",
        "Jeanne d'Arc écoutant les voix by Eugène Thirion (1876, Notre Dame Church, Ville de Chatou)\n",
        "Joan's visions played an important role in her condemnation, and her admission that she had returned to heeding them led to her execution.[289] Theologians of the era believed that visions could have a supernatural source.[290] The assessors at her trial focused on determining the specific source of Joan's visions,[291] using an ecclesiastical form of discretio spirituum (discernment of spirits).[292] Because she was accused of heresy, they sought to show that her visions were false.[293] The rehabilitation trial nullified Joan's sentence, but did not declare her visions authentic.[294] In 1894, Pope Leo XIII pronounced that Joan's mission was divinely inspired.[295]\n",
        "\n",
        "Modern scholars have discussed possible neurological and psychiatric causes for her visions.[296] Her visions have been described as hallucinations arising from epilepsy[297] or a temporal lobe tuberculoma.[298] Others have implicated ergot poisoning,[299] schizophrenia,[300] delusional disorder,[301] or creative psychopathy induced by her early childhood rearing.[302] One of the Promoters of the Faith at her 1903 canonization trial argued that her visions may have been manifestations of hysteria.[303] Other scholars argue that Joan created some of the visions' specific details in response to the demands of the interrogators at her trial.[304]\n",
        "\n",
        "Many of these explanations have been challenged;[g] the trial records designed to demonstrate that Joan was guilty of heresy are unlikely to provide the objective descriptions of symptoms needed to support a medical diagnosis.[306]\n",
        "\n",
        "Joan's firm belief in the divinity of her visions strengthened her confidence, enabled her to trust herself,[307] and gave her hope during her capture and trial.[308]\n",
        "\n",
        "Clothing\n",
        "Main article: Cross-dressing, gender identity, and sexuality of Joan of Arc\n",
        "Joan's cross-dressing was the topic of five of the articles of accusation against her during the trial.[309] In the view of the assessors, it was the emblem of her heresy.[310] Her final condemnation began when she was found to have resumed wearing men's clothes,[311] which was taken as a sign that she had relapsed into heresy.[312]\n",
        "\n",
        "see caption\n",
        "Jeanne d'Arc, a gilded bronze statue by Emmanuel Frémiet (1874, Place des Pyramides)\n",
        "From the time of her journey to Chinon to her abjuration, Joan usually wore men's clothes[313] and cropped her hair in a male fashion.[314] When she left Vaucouleurs to see the Dauphin in Chinon, Joan was said to have worn a black doublet, a black tunic, and a short black cap.[315] By the time she was captured, she had acquired more elaborate outfits. At her trial, she was accused of wearing breeches, a mantle, a coat of mail, a doublet, hose joined to the doublet with twenty laces, tight boots, spurs, a breastplate, buskins, a sword, a dagger, and a lance. She was also described as wearing furs, a golden surcoat over her armor, and sumptuous riding habits made of precious cloth.[316]\n",
        "\n",
        "During the trial proceedings, Joan is not recorded as giving a practical reason why she cross-dressed.[317] She stated that it was her own choice to wear men's clothes,[318] and that she did so not at the request of men but by the command of God and his angels.[319] She stated she would return to wearing women's clothes when she fulfilled her calling.[320]\n",
        "\n",
        "Although Joan's cross-dressing was used to justify her execution, the church's position on it was not clear. In general, it was seen as a sin, but there was no agreement about its severity.[321] Thomas Aquinas stated that a woman may wear a man's clothes to hide herself from enemies or if no other clothes were available,[322] and Joan did both, wearing them in enemy territory to get to Chinon,[323] and in her prison cell after her abjuration when her dress was taken from her.[324] Soon after the siege of Orléans was lifted, Jean Gerson said that Joan's male clothes and haircut were appropriate for her calling, as she was a warrior and men's clothes were more practical.[325]\n",
        "\n",
        "Cross-dressing may have helped her maintain her virginity by deterring rape:[326] witnesses at the nullification trial stated that Joan gave this as one of the reasons for returning to men's clothes after she had abjured wearing them.[327] However, scholars have stated that when she was imprisoned, wearing men's clothes would only have been a minor deterrent to rape as she was shackled most of the time.[328] For most of her active life, Joan did not cross-dress to hide her gender.[329] Rather, it may have functioned to emphasize her unique identity[330] as La Pucelle, a model of virtue that transcends gender roles and inspires people.[331]\n",
        "\n",
        "Legacy\n",
        "Joan is one of the most studied people of the Middle Ages,[332] partly because her two trials provided a wealth of documents.[333] Her image, changing over time, has included being the savior of France, an obedient daughter of the Roman Catholic Church, an early feminist, and a symbol of freedom and independence.[334]\n",
        "\n",
        "Military leader and symbol of France\n",
        "Joan of Arc on horseback, with sword in right hand\n",
        "Joan of Arc, statue by Denis Foyatier (1855, Orléans)\n",
        "Joan's reputation as a military leader who helped drive the English from France began to form before her death. Just after Charles's coronation, Christine de Pizan wrote the poem Ditié de Jehanne D'Arc, celebrating Joan as a supporter of Charles sent by Divine Providence and reflecting French optimism after the triumph at Orléans.[335] As early as 1429, Orléans began holding a celebration in honor of the raising of the siege on 8 May.[336]\n",
        "\n",
        "After Joan's execution, her role in the Orléans victory encouraged popular support for her rehabilitation.[337] Joan became a central part of the annual celebration, and by 1435, a play, Mistère du siège d'Orléans (Mystery of the Siege of Orléans),[338] portrayed her as the vehicle of the divine will that liberated Orléans.[339] The Orléans festival celebrating Joan continues in modern times.[340]\n",
        "\n",
        "Less than a decade after her rehabilitation trial, Pope Pius II wrote a brief biography describing her as the maid who saved the kingdom of France.[341] Louis XII commissioned a full-length biography of her c. 1500.[342]\n",
        "\n",
        "Joan's early legacy was closely associated with the divine right of the monarchy to rule France.[343] During the French Revolution, her reputation came into question because of her association with the monarchy and religion,[344] and the festival in her honor held at Orléans was suspended in 1793.[345] In 1803, Napoleon Bonaparte authorized its renewal[346] and the creation of a new statue of Joan at Orléans, stating, \"The illustrious Joan ... proved that there is no miracle which French genius cannot accomplish when national independence is threatened.\"[347]\n",
        "\n",
        "Since then, she has become a prominent symbol as the defender of the French nation. After the French defeat in the Franco-Prussian War, Joan became a rallying point for a new crusade to reclaim Lorraine, the province of her birth.[348] The Third Republic held a patriotic civic holiday in her honor[349] on 8 May to celebrate her victory at Orléans.[350] During World War I, her image was used to inspire victory.[351] In World War II, all sides of the French cause appealed to her legacy:[352] she was a symbol for Philippe Pétain in Vichy France,[353] a model for Charles de Gaulle's leadership of the Free French,[354] and an example for the Communist resistance.[355] More recently, her association with the monarchy and national liberation has made her a symbol for the French far right, including the monarchist movement Action Française[356] and the National Front Party.[357] Joan's image has been used by the entire spectrum of French politics,[358] and she is an important reference in political dialogue about French identity and unity.[359]\n",
        "\n",
        "Saint and heroic woman\n",
        "Joan of Arc depicted with short black hair in full body armor holding a flag and a sword; the breastplate reads \"Jesus and Mary\" in Latin\n",
        "Illustration by Albert Lynch (1903, in Figaro Illustré magazine)\n",
        "Joan is a saint in the Roman Catholic Church. She was viewed as a religious figure in Orléans after the siege was lifted, and an annual panegyric was pronounced there on her behalf until the 1800s.[360] In 1849, the Bishop of Orlėans Félix Dupanloup delivered an oration that attracted international attention[361] and in 1869, petitioned Rome to begin beatification proceedings.[362] She was beatified by Pope Pius X in 1909, and canonized on 16 May 1920 by Pope Benedict XV.[363] Her feast day is 30 May, the anniversary of her execution.[364] In an apostolic letter, Pope Pius XI declared Joan one of the patron saints of France on 2 March 1922.[365]\n",
        "\n",
        "Joan was canonized as a Virgin,[366] not as a Christian martyr[367] because she had been put to death by a canonically constituted court,[368] which executed her not for her faith in Christ,[369] but for her private revelation.[370] Nevertheless, she has been popularly venerated as a martyr since her death:[371] one who suffered for her modesty and purity,[372] her country,[373] and the strength of her convictions.[374] Joan is also remembered as a visionary in the Church of England with a commemoration on 30 May.[2] She is revered in the pantheon of the Cao Dai religion.[375]\n",
        "\n",
        "During her lifetime, Joan was already being compared to biblical women heroes, such as Esther, Judith, and Deborah.[376] Her claim of virginity, which signified her virtue and sincerity,[377] was upheld by women of status from both the Armagnac and Burgundian-English sides of the Hundred Years' War: Yolande of Aragon, Charles's mother-in-law, and Anne of Burgundy, Duchess of Bedford.[378]\n",
        "\n",
        "Joan has been described as a model of an autonomous woman who challenged traditions of masculinity and femininity[379] to be heard as an individual[380] in a patriarchal culture[380]—setting her own course by heeding the voices of her visions.[381] She fulfilled the traditionally male role of a military leader,[382] while maintaining her status as a valiant woman.[383] Merging qualities associated with both genders,[384] Joan has inspired numerous artistic and cultural works for many centuries. In the nineteenth century, hundreds of works of art about her—including biographies, plays, and musical scores—were created in France, and her story became popular as an artistic subject in Europe and North America.[385] By the 1960s, she was the topic of thousands of books.[386] Her legacy has become global, and inspires novels, plays, poems, operas, films, paintings, children's books, advertising, computer games, comics and popular culture across the world.[387]\n",
        "\"\"\")"
      ],
      "metadata": {
        "id": "KhyUkw6vQ_1B"
      },
      "execution_count": 13,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "from neo4j_graphrag.experimental.components.entity_relation_extractor import (\n",
        "    LLMEntityRelationExtractor,\n",
        ")\n",
        "from neo4j_graphrag.llm import OpenAILLM\n",
        "\n",
        "extractor = LLMEntityRelationExtractor(\n",
        "    llm=OpenAILLM(\n",
        "        model_name=\"gpt-4o\",\n",
        "        model_params={\n",
        "            \"max_tokens\": 1000,\n",
        "            \"response_format\": {\"type\": \"json_object\"},\n",
        "        },\n",
        "    )\n",
        ")"
      ],
      "metadata": {
        "id": "DPm--IyHQKON"
      },
      "execution_count": 11,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "# Hardcore hallucinations\n",
        "await extractor.run(docs, schema=schema)"
      ],
      "metadata": {
        "id": "Ch7nn1o5QtRy",
        "outputId": "590459cf-2c20-484c-acd3-972af19f9d50",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 849
        }
      },
      "execution_count": 15,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            "/usr/local/lib/python3.10/dist-packages/neo4j_graphrag/experimental/components/entity_relation_extractor.py:424: UserWarning: No document metadata provided, the document node won't be created in the lexical graph\n",
            "  warnings.warn(\n"
          ]
        },
        {
          "output_type": "error",
          "ename": "LLMGenerationError",
          "evalue": "LLM response has improper format {'nodes': [{'id': '0', 'label': 'Gene', 'properties': {'gene_id': 'BRCA1', 'symbol': 'BRCA1', 'full_name': 'BRCA1, DNA repair associated', 'chromosome': '17', 'location': '17q21.31'}}, {'id': '1', 'label': 'Disease', 'properties': {'disease_id': 'D001943', 'name': 'Breast Cancer', 'category': 'Cancer', 'description': 'A malignant neoplasm of the breast.'}}, {'id': '2', 'label': 'Drug', 'properties': {'drug_id': 'DB01229', 'name': 'Tamoxifen', 'type': 'Selective Estrogen Receptor Modulator', 'mechanism_of_action': 'Blocks estrogen receptors in breast tissue.'}}], 'relationships': [{'type': 'ASSOCIATED_WITH', 'start_node_id': '0', 'end_node_id': '1', 'properties': []}, {'type': 'TARGETS', 'start_node_id': '2', 'end_node_id': '0', 'properties': []}]}: 2 validation errors for Neo4jGraph\nrelationships.0.properties\n  Input should be a valid dictionary [type=dict_type, input_value=[], input_type=list]\n    For further information visit https://errors.pydantic.dev/2.9/v/dict_type\nrelationships.1.properties\n  Input should be a valid dictionary [type=dict_type, input_value=[], input_type=list]\n    For further information visit https://errors.pydantic.dev/2.9/v/dict_type",
          "traceback": [
            "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
            "\u001b[0;31mValidationError\u001b[0m                           Traceback (most recent call last)",
            "\u001b[0;32m/usr/local/lib/python3.10/dist-packages/neo4j_graphrag/experimental/components/entity_relation_extractor.py\u001b[0m in \u001b[0;36mextract_for_chunk\u001b[0;34m(self, schema, examples, chunk)\u001b[0m\n\u001b[1;32m    348\u001b[0m         \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 349\u001b[0;31m             \u001b[0mchunk_graph\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mNeo4jGraph\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m**\u001b[0m\u001b[0mresult\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    350\u001b[0m         \u001b[0;32mexcept\u001b[0m \u001b[0mValidationError\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0me\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
            "\u001b[0;32m/usr/local/lib/python3.10/dist-packages/pydantic/main.py\u001b[0m in \u001b[0;36m__init__\u001b[0;34m(self, **data)\u001b[0m\n\u001b[1;32m    208\u001b[0m         \u001b[0m__tracebackhide__\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mTrue\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 209\u001b[0;31m         \u001b[0mvalidated_self\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m__pydantic_validator__\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mvalidate_python\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdata\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself_instance\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    210\u001b[0m         \u001b[0;32mif\u001b[0m \u001b[0mself\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0mvalidated_self\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
            "\u001b[0;31mValidationError\u001b[0m: 2 validation errors for Neo4jGraph\nrelationships.0.properties\n  Input should be a valid dictionary [type=dict_type, input_value=[], input_type=list]\n    For further information visit https://errors.pydantic.dev/2.9/v/dict_type\nrelationships.1.properties\n  Input should be a valid dictionary [type=dict_type, input_value=[], input_type=list]\n    For further information visit https://errors.pydantic.dev/2.9/v/dict_type",
            "\nDuring handling of the above exception, another exception occurred:\n",
            "\u001b[0;31mLLMGenerationError\u001b[0m                        Traceback (most recent call last)",
            "\u001b[0;32m<ipython-input-15-43053a76c7e4>\u001b[0m in \u001b[0;36m<cell line: 1>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0;32mawait\u001b[0m \u001b[0mextractor\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrun\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdocs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mschema\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mschema\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
            "\u001b[0;32m/usr/local/lib/python3.10/dist-packages/neo4j_graphrag/experimental/components/entity_relation_extractor.py\u001b[0m in \u001b[0;36mrun\u001b[0;34m(self, chunks, document_info, schema, examples, **kwargs)\u001b[0m\n\u001b[1;32m    442\u001b[0m             \u001b[0;32mfor\u001b[0m \u001b[0mchunk\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mchunks\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mchunks\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    443\u001b[0m         ]\n\u001b[0;32m--> 444\u001b[0;31m         \u001b[0mchunk_graphs\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mlist\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mNeo4jGraph\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mlist\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;32mawait\u001b[0m \u001b[0masyncio\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mgather\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0mtasks\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    445\u001b[0m         \u001b[0mgraph\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcombine_chunk_graphs\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mlexical_graph\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mchunk_graphs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    446\u001b[0m         \u001b[0mlogger\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdebug\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34mf\"{self.__class__.__name__}: {graph}\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
            "\u001b[0;32m/usr/local/lib/python3.10/dist-packages/neo4j_graphrag/experimental/components/entity_relation_extractor.py\u001b[0m in \u001b[0;36mrun_for_chunk\u001b[0;34m(self, sem, run_id, chunk, schema, examples, lexical_graph_builder, document_id)\u001b[0m\n\u001b[1;32m    400\u001b[0m         \u001b[0;34m\"\"\"Run extraction and post processing for a single chunk\"\"\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    401\u001b[0m         \u001b[0;32masync\u001b[0m \u001b[0;32mwith\u001b[0m \u001b[0msem\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 402\u001b[0;31m             \u001b[0mchunk_graph\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mawait\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mextract_for_chunk\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mschema\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mexamples\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mchunk\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    403\u001b[0m             await self.post_process_chunk(\n\u001b[1;32m    404\u001b[0m                 \u001b[0mchunk_graph\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mchunk\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mrun_id\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mlexical_graph_builder\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdocument_id\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
            "\u001b[0;32m/usr/local/lib/python3.10/dist-packages/neo4j_graphrag/experimental/components/entity_relation_extractor.py\u001b[0m in \u001b[0;36mextract_for_chunk\u001b[0;34m(self, schema, examples, chunk)\u001b[0m\n\u001b[1;32m    350\u001b[0m         \u001b[0;32mexcept\u001b[0m \u001b[0mValidationError\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0me\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    351\u001b[0m             \u001b[0;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mon_error\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0mOnError\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mRAISE\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 352\u001b[0;31m                 raise LLMGenerationError(\n\u001b[0m\u001b[1;32m    353\u001b[0m                     \u001b[0;34mf\"LLM response has improper format {result}: {e}\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    354\u001b[0m                 )\n",
            "\u001b[0;31mLLMGenerationError\u001b[0m: LLM response has improper format {'nodes': [{'id': '0', 'label': 'Gene', 'properties': {'gene_id': 'BRCA1', 'symbol': 'BRCA1', 'full_name': 'BRCA1, DNA repair associated', 'chromosome': '17', 'location': '17q21.31'}}, {'id': '1', 'label': 'Disease', 'properties': {'disease_id': 'D001943', 'name': 'Breast Cancer', 'category': 'Cancer', 'description': 'A malignant neoplasm of the breast.'}}, {'id': '2', 'label': 'Drug', 'properties': {'drug_id': 'DB01229', 'name': 'Tamoxifen', 'type': 'Selective Estrogen Receptor Modulator', 'mechanism_of_action': 'Blocks estrogen receptors in breast tissue.'}}], 'relationships': [{'type': 'ASSOCIATED_WITH', 'start_node_id': '0', 'end_node_id': '1', 'properties': []}, {'type': 'TARGETS', 'start_node_id': '2', 'end_node_id': '0', 'properties': []}]}: 2 validation errors for Neo4jGraph\nrelationships.0.properties\n  Input should be a valid dictionary [type=dict_type, input_value=[], input_type=list]\n    For further information visit https://errors.pydantic.dev/2.9/v/dict_type\nrelationships.1.properties\n  Input should be a valid dictionary [type=dict_type, input_value=[], input_type=list]\n    For further information visit https://errors.pydantic.dev/2.9/v/dict_type"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "docs = await splitter.run(text=\"\"\"\n",
        "Angiotensin-converting enzyme 2 (ACE2)[5] is an enzyme that can be found either attached to the membrane of cells (mACE2) in the intestines, kidney, testis, gallbladder, and heart or in a soluble form (sACE2).[6][7][8] Both membrane bound and soluble ACE2 are integral parts of the renin–angiotensin–aldosterone system (RAAS) that exists to keep the body's blood pressure in check. mACE2 is cleaved by the enzyme ADAM17 in a process regulated by substrate presentation. ADAM17 cleavage releases the extracellular domain creating soluble ACE2 (sACE2).[9] ACE2 enzyme activity opposes the classical arm of the RAAS by lowering blood pressure through catalyzing the hydrolysis of angiotensin II (a vasoconstrictor peptide which raises blood pressure) into angiotensin (1–7) (a vasodilator).[8][10][11] Angiotensin (1-7) in turns binds to MasR receptors creating localized vasodilation and hence decreasing blood pressure.[12] This decrease in blood pressure makes the entire process a promising drug target for treating cardiovascular diseases.[13][14]\n",
        "\n",
        "mACE2 also serves as the entry point into cells for some coronaviruses, including HCoV-NL63, SARS-CoV, and SARS-CoV-2.[5] The SARS-CoV-2 spike protein itself is known to damage the endothelium via downregulation of ACE2.[15] The human version of the enzyme can be referred to as hACE2.[16]\n",
        "\n",
        "Structure\n",
        "Angiotensin-converting enzyme 2\n",
        "Identifiers\n",
        "EC no.\t3.4.17.23\n",
        "Databases\n",
        "IntEnz\tIntEnz view\n",
        "BRENDA\tBRENDA entry\n",
        "ExPASy\tNiceZyme view\n",
        "KEGG\tKEGG entry\n",
        "MetaCyc\tmetabolic pathway\n",
        "PRIAM\tprofile\n",
        "PDB structures\tRCSB PDB PDBe PDBsum\n",
        "Search\n",
        "Membrane bound angiotensin-converting enzyme 2 (mACE2) is a zinc-containing metalloenzyme located on the surface of intestinal enterocytes, renal tubular cells and other cells.[6][17] mACE2 protein contains an N-terminal peptidase M2 domain and a C-terminal collectrin renal amino acid transporter domain.[17]\n",
        "\n",
        "mACE2 is a single-pass type I membrane protein, with its enzymatically active domain exposed on the surface of cells in the intestines and other tissues.[6][7] The extracellular domain of mACE2 can be cleaved from the transmembrane domain by another enzyme known as ADAM17 a member of the sheddase enzyme family, during the protective phase of RAAS, the Renin–Angiotension–Aldosterone System, which regulates our body's blood pressure. The resulting cleaved protein is known as soluble ACE2 or sACE2. It is released into the bloodstream where one of sACE2's functions is to turn excess angiotensin II into angiotensin 1-7 which binds to MasR receptors creating localized vasodilation and hence decreasing blood pressure. Excess sACE2 may ultimately be excreted in the urine.[18][19]\n",
        "\n",
        "Location within the human body\n",
        "mACE2 is attached to the cell membrane of mainly enterocytes of the small intestine and duodenum, proximal tubular cells of the kidneys, glandular cells of the gallbladder, as well as Sertoli cells and Leydig cells of the testis.[6] The expression profile of mACE2 in the human body was recently thoroughly evaluated by the Human Protein Atlas team using a large-scale multiomics approach combining several different methods for analysis of gene expression, including a stringent immunohistochemical analysis using two independent antibodies.[6][20] In addition to the above-mentioned issues, mACE2 expression was also seen in endothelial cells and pericytes of blood vessels within certain tissues, cardiomyocytes in heart tissue, and a smaller subset of cells within the thyroid gland, epididymis, seminal vesicle, pancreas, liver and placenta. Despite the fact that the respiratory system is the primary route of SARS-CoV-2 infection, very limited expression is seen, both at protein and mRNA level. The expression within the respiratory system is mainly restricted to the upper bronchial and nasal epithelia, especially in the ciliated cells.[21]\n",
        "\n",
        "Function\n",
        "As part of the renin–angiotensin–aldosterone system (RAAS) protective phase, soluble ACE2's (sACE2) important function is to act as a counterbalance to the angiotensin-converting enzyme (ACE). ACE cleaves angiotensin I hormone into the vasoconstricting angiotensin II which causes a cascade of hormonal reactions which is part of the body's harmful phase of RAAS, which ultimately leads to an increase in the body's blood pressure. ACE2 has an opposing effect to ACE, degrading angiotensin II into angiotensin (1-7), thereby lowering blood pressure.[22][23]\n",
        "\n",
        "sACE2, as part of RAAS's protective phase, cleaves the carboxyl-terminal amino acid phenylalanine from angiotensin II (Asp-Arg-Val-Tyr-Ile-His-Pro-Phe) and hydrolyses it into the vasodilator angiotensin (1-7) (H-Asp-Arg-Val-Tyr-Ile-His-Pro-OH), which binds to Mas Receptors and ultimately leads to a decrease in blood pressure.[24][17] sACE2 can also cleave numerous peptides, including [des-Arg9]-bradykinin, apelin, neurotensin, dynorphin A, and ghrelin.[17]\n",
        "\n",
        "mACE2 also regulates the membrane trafficking of the neutral amino acid transporter SLC6A19 and has been implicated in Hartnup's disease.[25][26][27]\n",
        "\n",
        "Research in mice has shown that ACE2 (whether it is the membrane bound version or soluble is inconclusive) is involved in regulation of the blood glucose level but its mechanism is yet to be confirmed.[28][29]\n",
        "\n",
        "Coronavirus entry point\n",
        "As a transmembrane protein, mACE2 serves as the main entry point into cells for some coronaviruses, including HCoV-NL63,[5] SARS-CoV (the virus that causes SARS),[30][31][32] and SARS-CoV-2[33] (the virus that causes COVID-19).[34][35][36][37][38] More specifically, the binding of the spike S1 protein of SARS-CoV and SARS-CoV-2 to the enzymatic domain of mACE2 on the surface of cells results in endocytosis and translocation of both the virus and the enzyme into endosomes located within cells.[39][40] In culture blocking endocytosis traps the virus on the surface.[41]\n",
        "\n",
        "The receptor-binding domain (RBD) of spike protein, located on the virus’s surface, specifically attaches to human cell receptors.[38] ACE2 is essential as it’s a cell surface receptor that lets the virus get into and infect cells. The spike protein’s RBD of SARS-CoV-2 links to ACE2, enabling viral entry and reproduction within cells.[38] In addition the attachment of SP-A and SP-D residues to ACE2 could potentially diminish the strength of the interaction between the spike protein and ACE2.[38]\n",
        "\n",
        "The binding of the SARS-CoV-2 virus through mACE2 receptors present in heart tissue may be responsible for direct viral injury leading to myocarditis. In a study done during the SARS outbreak, SARS virus RNA was ascertained in the autopsy of heart specimens in 35% of the patients who died due to SARS.[42] It was also observed that an already diseased heart has increased expression of mACE2 receptors contrasted to healthy individuals.[43] This entry process also requires priming of the S protein by the host serine protease TMPRSS2, the inhibition of which is under current investigation as a potential therapeutic.[44][21] It has also been shown that disruption of S-protein glycosylation significantly impairs viral entry, indicating the importance of glycan-protein interactions in the process.[45]\n",
        "\n",
        "This has led some to hypothesize that decreasing the levels of mACE2, in cells, might help in fighting the infection. Furthermore, according to studies conducted on mice, the interaction of the spike protein of the coronavirus with mACE2 induces a drop in the levels of mACE2 in cells through internalization and degradation of the protein and hence may contribute to lung damage.[46][47]\n",
        "\n",
        "On the other hand, sACE2 has been shown to have a protective effect against virus-induced lung injury by increasing the production of the vasodilator angiotensin 1–7.[46] Furthermore, some researchers have hypothesized that sACE2 (which is created during the Protective Phase of RAAS) is not only involved in binding to angiotensin II to create angiotensin I-7, which lowers blood pressure by vasodilation, but that free and soluble ACE2 may also be binding to coronavirus spike proteins, hence making those coronavirus spikes unavailable for binding to mACE-2 sites.[37] But even with only tiny amounts of mACE2, SARS-CoV-2 virus can gain entry into cells if TMPRSS2 is present.[48]\n",
        "\n",
        "Both ACE inhibitors and angiotensin II receptor blockers (ARBs) that are used to treat high blood pressure have been shown in rodent studies to upregulate mACE2 expression, possibly affecting the severity of coronavirus infections.[49][50]\n",
        "\n",
        "However, a systematic review and meta-analysis published on July 11, 2012, found that \"use of ACE inhibitors was associated with a significant 34% reduction in risk of pneumonia compared with controls.\" Moreover, \"the risk of pneumonia was also reduced in patients treated with ACE inhibitors who were at higher risk of pneumonia, in particular those with stroke and heart failure. Use of ACE inhibitors was also associated with a reduction in pneumonia related mortality, although the results were less robust than for overall risk of pneumonia.\"[51] An April 2020 study of patients hospitalized in Hubei Province in China found a death rate of 3.7% for patients with hypertension who were taking ACE inhibitors or ARBs. The death rate was compared with 9.8% of hospitalized patients with hypertension not taking such drugs, suggesting that ACE inhibitors and ARBs are not harmful and may help against the coronavirus.[52]\n",
        "\n",
        "Despite lack of conclusive evidence, some have advocated for or against the cessation of ACE inhibitor or ARB treatment in COVID-19 patients with hypertension.[53] However, multiple professional societies and regulatory bodies have recommended continuing standard ACE inhibitor and ARB therapy.[54][55][56]\n",
        "\n",
        "Plasma ACE2 levels predict outcome of COVID-19 in hospitalized patients, with higher plasma levels being correlated with worse disease outcomes. Patients with high blood pressure or heart disease show elevated ACE2 plasma levels.[57]\n",
        "\n",
        "Given its role as the SARS-CoV-2 entry receptor, it has been repeatedly hypothesised that population variation in ACE2 may contribute to an individual's genetic susceptibility to COVID-19.[58][59] Several studies have reported that ACE2 missense variants can alter its binding affinity for the spike protein,[60][61][62] and consequently its susceptibility to SARS-CoV-2 pseudovirus entry,[63] and there is strong evidence of individuals who carry rare variants in ACE2 that could confer total resistance to SARS-CoV-2 infection.[62] The expression level of ACE2 at the cell surface is another critical factor affecting viral susceptibility and probably plays a role in the tissue tropism of the virus[63] and many suspected COVID-19 associated ACE2 variants affect expression.[59] In fact, SARS-CoV-2's viral tropism is dependent on ACE2 tissue distribution and expression.[64] For example, genetic variants placed in the X chromosome (rs190509934:C) have been related to lower expression levels of ACE2 enzyme. This would lead to an increased number of entries and infections performed by the SARS-CoV-2 virus. Moreover, those variants have shown a 37% reduction in expression of the protein and a remarkable protection from severe outcomes (respiratory failure and death).[65]\n",
        "\n",
        "Recombinant human ACE2\n",
        "Recombinant human ACE2 (rhACE2) is surmised to be a novel therapy for acute lung injury, and appeared to improve pulmonary blood flow and oxygen saturation in piglets with a lipopolysaccharide-induced acute respiratory distress syndrome.[66] The half-life of rhACE2 in human beings is about 10 hours, and the onset of action is 30 minutes in addition to the course of effect (duration) of 24 hours.[66] Several findings suggest that rhACE2 may be a promising drug for those with intolerance to classic renin–angiotensin system inhibitors (RAS inhibitors) or in diseases where circulating angiotensin II is elevated.[66]\n",
        "\n",
        "An in vitro study focused on the early stages of infection found that clinical-grade human recombinant soluble ACE2 (hrsACE2) reduced SARS-CoV-2 recovery from vero cells by a factor of 1,000–5,000. The equivalent mouse rsACE2 did not have such an effect. This study suggests that rhsACE2 not only restores the renin-angiotensin system to balance as in the earlier ARDS studies, but also directly slows down infection by this virus – possibly as a decoy.[67] ACE2 mutants have been engineered with even higher affinity for SARS-CoV-2 Spike and shown to effectively neutralise the virus in vitro.[68] An ACE2 triple mutant that displayed nanomolar binding to Spike (sACE2.v2.4),[68] was later shown to block pseudovirus cell entry in human lung cell lines and prevent SARS-CoV-2 induced ARDS in an ACE2 humanized mouse model.[69]\n",
        "\n",
        "Infused rhACE2 has been evaluated in clinical trials for the treatment of acute respiratory distress syndrome (ARDS).[70] rhACE2 is in phase II trial for severe COVID-19.[71]\n",
        "\"\"\")"
      ],
      "metadata": {
        "id": "nCHyzVnuSWBx"
      },
      "execution_count": 16,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "await extractor.run(docs, schema=schema)"
      ],
      "metadata": {
        "id": "fLvmZHV2SAhm",
        "outputId": "0df1087c-5850-43e8-eca9-244ee676d0f2",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 900
        }
      },
      "execution_count": 17,
      "outputs": [
        {
          "output_type": "error",
          "ename": "LLMGenerationError",
          "evalue": "LLM response has improper format {'nodes': [{'id': '0', 'label': 'Gene', 'properties': {'gene_id': '', 'symbol': 'ACE2', 'full_name': '', 'chromosome': '', 'location': ''}}, {'id': '1', 'label': 'Disease', 'properties': {'disease_id': '', 'name': 'COVID-19', 'category': '', 'description': ''}}, {'id': '2', 'label': 'Disease', 'properties': {'disease_id': '', 'name': 'high blood pressure', 'category': '', 'description': ''}}, {'id': '3', 'label': 'Disease', 'properties': {'disease_id': '', 'name': 'heart disease', 'category': '', 'description': ''}}], 'relationships': [{'type': 'ASSOCIATED_WITH', 'start_node_id': '0', 'end_node_id': '1', 'properties': []}, {'type': 'ASSOCIATED_WITH', 'start_node_id': '0', 'end_node_id': '2', 'properties': []}, {'type': 'ASSOCIATED_WITH', 'start_node_id': '0', 'end_node_id': '3', 'properties': []}]}: 3 validation errors for Neo4jGraph\nrelationships.0.properties\n  Input should be a valid dictionary [type=dict_type, input_value=[], input_type=list]\n    For further information visit https://errors.pydantic.dev/2.9/v/dict_type\nrelationships.1.properties\n  Input should be a valid dictionary [type=dict_type, input_value=[], input_type=list]\n    For further information visit https://errors.pydantic.dev/2.9/v/dict_type\nrelationships.2.properties\n  Input should be a valid dictionary [type=dict_type, input_value=[], input_type=list]\n    For further information visit https://errors.pydantic.dev/2.9/v/dict_type",
          "traceback": [
            "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
            "\u001b[0;31mValidationError\u001b[0m                           Traceback (most recent call last)",
            "\u001b[0;32m/usr/local/lib/python3.10/dist-packages/neo4j_graphrag/experimental/components/entity_relation_extractor.py\u001b[0m in \u001b[0;36mextract_for_chunk\u001b[0;34m(self, schema, examples, chunk)\u001b[0m\n\u001b[1;32m    348\u001b[0m         \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 349\u001b[0;31m             \u001b[0mchunk_graph\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mNeo4jGraph\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m**\u001b[0m\u001b[0mresult\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    350\u001b[0m         \u001b[0;32mexcept\u001b[0m \u001b[0mValidationError\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0me\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
            "\u001b[0;32m/usr/local/lib/python3.10/dist-packages/pydantic/main.py\u001b[0m in \u001b[0;36m__init__\u001b[0;34m(self, **data)\u001b[0m\n\u001b[1;32m    208\u001b[0m         \u001b[0m__tracebackhide__\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mTrue\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 209\u001b[0;31m         \u001b[0mvalidated_self\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m__pydantic_validator__\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mvalidate_python\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdata\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself_instance\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    210\u001b[0m         \u001b[0;32mif\u001b[0m \u001b[0mself\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0mvalidated_self\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
            "\u001b[0;31mValidationError\u001b[0m: 3 validation errors for Neo4jGraph\nrelationships.0.properties\n  Input should be a valid dictionary [type=dict_type, input_value=[], input_type=list]\n    For further information visit https://errors.pydantic.dev/2.9/v/dict_type\nrelationships.1.properties\n  Input should be a valid dictionary [type=dict_type, input_value=[], input_type=list]\n    For further information visit https://errors.pydantic.dev/2.9/v/dict_type\nrelationships.2.properties\n  Input should be a valid dictionary [type=dict_type, input_value=[], input_type=list]\n    For further information visit https://errors.pydantic.dev/2.9/v/dict_type",
            "\nDuring handling of the above exception, another exception occurred:\n",
            "\u001b[0;31mLLMGenerationError\u001b[0m                        Traceback (most recent call last)",
            "\u001b[0;32m<ipython-input-17-43053a76c7e4>\u001b[0m in \u001b[0;36m<cell line: 1>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0;32mawait\u001b[0m \u001b[0mextractor\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrun\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdocs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mschema\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mschema\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
            "\u001b[0;32m/usr/local/lib/python3.10/dist-packages/neo4j_graphrag/experimental/components/entity_relation_extractor.py\u001b[0m in \u001b[0;36mrun\u001b[0;34m(self, chunks, document_info, schema, examples, **kwargs)\u001b[0m\n\u001b[1;32m    442\u001b[0m             \u001b[0;32mfor\u001b[0m \u001b[0mchunk\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mchunks\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mchunks\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    443\u001b[0m         ]\n\u001b[0;32m--> 444\u001b[0;31m         \u001b[0mchunk_graphs\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mlist\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mNeo4jGraph\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mlist\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;32mawait\u001b[0m \u001b[0masyncio\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mgather\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0mtasks\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    445\u001b[0m         \u001b[0mgraph\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcombine_chunk_graphs\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mlexical_graph\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mchunk_graphs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    446\u001b[0m         \u001b[0mlogger\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdebug\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34mf\"{self.__class__.__name__}: {graph}\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
            "\u001b[0;32m/usr/local/lib/python3.10/dist-packages/neo4j_graphrag/experimental/components/entity_relation_extractor.py\u001b[0m in \u001b[0;36mrun_for_chunk\u001b[0;34m(self, sem, run_id, chunk, schema, examples, lexical_graph_builder, document_id)\u001b[0m\n\u001b[1;32m    400\u001b[0m         \u001b[0;34m\"\"\"Run extraction and post processing for a single chunk\"\"\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    401\u001b[0m         \u001b[0;32masync\u001b[0m \u001b[0;32mwith\u001b[0m \u001b[0msem\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 402\u001b[0;31m             \u001b[0mchunk_graph\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mawait\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mextract_for_chunk\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mschema\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mexamples\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mchunk\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    403\u001b[0m             await self.post_process_chunk(\n\u001b[1;32m    404\u001b[0m                 \u001b[0mchunk_graph\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mchunk\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mrun_id\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mlexical_graph_builder\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdocument_id\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
            "\u001b[0;32m/usr/local/lib/python3.10/dist-packages/neo4j_graphrag/experimental/components/entity_relation_extractor.py\u001b[0m in \u001b[0;36mextract_for_chunk\u001b[0;34m(self, schema, examples, chunk)\u001b[0m\n\u001b[1;32m    350\u001b[0m         \u001b[0;32mexcept\u001b[0m \u001b[0mValidationError\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0me\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    351\u001b[0m             \u001b[0;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mon_error\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0mOnError\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mRAISE\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 352\u001b[0;31m                 raise LLMGenerationError(\n\u001b[0m\u001b[1;32m    353\u001b[0m                     \u001b[0;34mf\"LLM response has improper format {result}: {e}\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    354\u001b[0m                 )\n",
            "\u001b[0;31mLLMGenerationError\u001b[0m: LLM response has improper format {'nodes': [{'id': '0', 'label': 'Gene', 'properties': {'gene_id': '', 'symbol': 'ACE2', 'full_name': '', 'chromosome': '', 'location': ''}}, {'id': '1', 'label': 'Disease', 'properties': {'disease_id': '', 'name': 'COVID-19', 'category': '', 'description': ''}}, {'id': '2', 'label': 'Disease', 'properties': {'disease_id': '', 'name': 'high blood pressure', 'category': '', 'description': ''}}, {'id': '3', 'label': 'Disease', 'properties': {'disease_id': '', 'name': 'heart disease', 'category': '', 'description': ''}}], 'relationships': [{'type': 'ASSOCIATED_WITH', 'start_node_id': '0', 'end_node_id': '1', 'properties': []}, {'type': 'ASSOCIATED_WITH', 'start_node_id': '0', 'end_node_id': '2', 'properties': []}, {'type': 'ASSOCIATED_WITH', 'start_node_id': '0', 'end_node_id': '3', 'properties': []}]}: 3 validation errors for Neo4jGraph\nrelationships.0.properties\n  Input should be a valid dictionary [type=dict_type, input_value=[], input_type=list]\n    For further information visit https://errors.pydantic.dev/2.9/v/dict_type\nrelationships.1.properties\n  Input should be a valid dictionary [type=dict_type, input_value=[], input_type=list]\n    For further information visit https://errors.pydantic.dev/2.9/v/dict_type\nrelationships.2.properties\n  Input should be a valid dictionary [type=dict_type, input_value=[], input_type=list]\n    For further information visit https://errors.pydantic.dev/2.9/v/dict_type"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [],
      "metadata": {
        "id": "aJ7epHlBbjC2"
      },
      "execution_count": null,
      "outputs": []
    }
  ]
}